#include "EnsUtilisateur.h"

void ensutInitialiser(EnsUtilisateur *pEnsUtilisateur)
{
    pEnsUtilisateur->Utilisateurs=NULL;
}


void ensutAjouter(EnsUtilisateur *pEnsUtilisateur, const Utilisateur* pUtilisateur)
{
    pEnsUtilisateur->Utilisateurs=g_list_insert_sorted(pEnsUtilisateur->Utilisateurs, (Utilisateur *)pUtilisateur, (GCompareFunc)utilisateurComparer);
}


void ensutSupprimer(EnsUtilisateur *pEnsUtilisateur, const char * Nom)
{
    Utilisateur* pResultat= (Utilisateur *)ensutRechercher(pEnsUtilisateur, Nom);
    pEnsUtilisateur->Utilisateurs=g_list_remove(pEnsUtilisateur->Utilisateurs, pResultat);
}


Utilisateur* ensutRechercher(const EnsUtilisateur *pEnsUtilisateur, const char* Nom)
{
    GList* pResultat= g_list_find_custom(pEnsUtilisateur->Utilisateurs, Nom, (GCompareFunc)utilisateurComparer);
    if(pResultat==NULL)
    {
        printf("contact non trouvé \n");
        return NULL;
    }
    else
    {
        return (Utilisateur*)g_list_nth_data(pResultat, 0);
    }
}


Utilisateur *ensutGetUtilisateur(const EnsUtilisateur *pEnsUtilisateur, int i)
{
    if (i>g_list_length(pEnsUtilisateur->Utilisateurs))
    {
        printf("l'utilisateur n'est pas dans la liste \n");
        return NULL;
    }
    else
    {
        return (Utilisateur *)g_list_nth_data((*pEnsUtilisateur).Utilisateurs, (guint)i);
    }
}


int ensutTaille(const EnsUtilisateur *pEnsUtilisateur)
{
    return  (int)g_list_length(pEnsUtilisateur->Utilisateurs);
}


void ensutAjouter2(EnsUtilisateur *pEnsUtilisateur)
{
    Utilisateur* u;
    utilisateurInitialiser(&u);
    utilisateurSaisir(u);
    ensutAjouter(pEnsUtilisateur, u);
}


void ensutLiberer(EnsUtilisateur *pEnsUtilisateur)
{
    g_list_free_full(pEnsUtilisateur->Utilisateurs, (GDestroyNotify)utilisateurLiberer);
    //g_list_free(pEnsUtilisateur->Utilisateurs);
    //pEnsUtilisateur->Utilisateurs=NULL;
    pEnsUtilisateur=NULL;
}


void ensutAfficher(const EnsUtilisateur* pEnsUtilisateur)
{
    int i;
    for (i=0; i< ensutTaille(pEnsUtilisateur); i++)
    {
        utilisateurAfficher(ensutGetUtilisateur(pEnsUtilisateur, i));
        printf("\n \n");
    }
}


void ensutSauver(const EnsUtilisateur *pEnsUtilisateur, const char * nomfichier)
{
    FILE* f;
    Utilisateur *putil;
    int i;

    f = fopen(nomfichier, "w");
    if (f==NULL)
    {
        printf("Erreur lors de l'ouverture de %s\n", nomfichier);
        assert( f );
    }
    fprintf(f , "EnsUtilisateur: \n");
    fprintf(f , "nbUtilisateur: %d \n", ensutTaille(pEnsUtilisateur));


    for(i=0; i< ensutTaille(pEnsUtilisateur); i++)
    {
        putil = ensutGetUtilisateur(pEnsUtilisateur, i);
        assert(fprintf(f,"nom: %s \n", utilisateurGetNom(putil))>=1);
        assert(fprintf(f,"prenom: %s \n", utilisateurGetPrenom(putil))>=1);
        assert(fprintf(f,"password: %s \n", utilisateurGetPassword(putil))>=1);
        assert(gmp_fprintf(f,"clef publique: (%Zd, %Zd) \n", ClefPubliqueGetn(utilisateurGetClefPublique(putil)), ClefPubliqueGetc(utilisateurGetClefPublique(putil)) )>=2);
        assert(gmp_fprintf(f,"clef privee: (%Zd, %Zd) \n", ClefPriveeGetu(utilisateurGetClefPrivee(putil)), ClefPriveeGetn(utilisateurGetClefPrivee(putil)) )>=2);
        assert(fprintf(f, "\n \n")>=0);
    }
    printf("Sauvegarde de l'EnsUtilisateur: %s ...OK \n \n", nomfichier);
    fclose(f);
}


void ensutCharger(EnsUtilisateur *pEnsUtilisateur, const char * nomfichier)
{
    FILE* f;
    Utilisateur *putil;

    int taille;
    int i;

    f = fopen(nomfichier, "r");

    /* Si le fichier n'existe pas on le crée: */
    if (f==NULL)
    {
        printf("Création du fichier %s\n", nomfichier);
        ensutSauver(pEnsUtilisateur, nomfichier);
        f = fopen(nomfichier, "r");
    }

    assert( fscanf( f , "EnsUtilisateur: \n nbUtilisateur: %d \n", &taille) >=0);
    ensutInitialiser(pEnsUtilisateur);

    for(i=0; i< taille; i++)
    {
        utilisateurInitialiser2(&putil);
        assert(fscanf(f,"nom: %s \n", (putil->Nom))>=1);
        assert(fscanf(f,"prenom: %s \n", (putil->Prenom))>=1);
        assert(fscanf(f,"password: %s \n", (putil->Password))>=1);
        assert(gmp_fscanf(f, "clef publique: (%Zd, %Zd) \n", &(putil->pClefPublique->n), &(putil->pClefPublique->c))>=2);
        assert(gmp_fscanf(f, "clef privee: (%Zd, %Zd) \n", &(putil->pClefPrivee->u), &(putil->pClefPrivee->n))>=2);
        assert(fscanf(f, "\n \n")>=0);
        ensutAjouter(pEnsUtilisateur, putil);
    }
    fclose(f);
    printf("Lecture de l'EnsUtilisateur: %s ...OK \n \n", nomfichier);
}


void testRegressionEnsut()
{
    printf("test regression EnsUtilisateur \n");
    EnsUtilisateur u1;
    EnsUtilisateur u2;
    Utilisateur * a;
//    utilisateurInitialiser(&a);
    ensutInitialiser(&u1);
    ensutAjouter2(&u1);
    ensutAjouter2(&u1);
    printf("voici la taille de EnsUtilisateur: %d \n", ensutTaille(&u1));
    ensutAjouter2(&u1);
    printf("voici la taille de EnsUtilisateur: %d \n", ensutTaille(&u1));
    ensutAfficher(&u1);
    //printf("voici le premier pointeur: %p \n", ensutGetUtilisateur(&u1, 1));
    ensutSauver(&u1, "testensut");
    ensutCharger(&u2, "testensut");
    ensutAfficher(&u2);

    printf("On teste la fonction de recherche : \n");
    a = ensutRechercher(&u2, "coladon");
    if (a!=NULL)
    {
        utilisateurAfficher(a);
        //utilisateurLiberer(a);
    }

    //contactAfficher(agendaGetContact(&a1, 1));
    //contactAfficher(agendaGetContact(&a1, 2));
    ensutLiberer(&u1);
    ensutLiberer(&u2);
    /* On ne libère pas a car l'adresse est déjà libérée par ensut libérée */
}
